package com.spz.demo.singleboot.controller;

import com.alibaba.fastjson.JSONArray;
import com.spz.demo.singleboot.common.CacheConst;
import com.spz.demo.singleboot.common.RequestMappingConst;
import com.spz.demo.singleboot.common.WebConst;
import com.spz.demo.singleboot.util.*;
import com.spz.demo.singleboot.vo.Response;
import com.spz.demo.singleboot.service.UserService;
import com.spz.demo.singleboot.shiro.token.UserAuthenticationToken;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.util.*;

/**
 * 用户控制器
 *
 * @author spz
 */
@Slf4j
@RestController(RequestMappingConst.BASIC_URL_USER)
@Validated
public class UserController {

    @Value("${jwt.period}")
    private Long period;//token有效时间（毫秒）
    @Value(("${jwt.issuer}"))
    private String issuer;//jwt token 签发人

    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private UserService userService;
    @Autowired
    private EhcacheUtil ehcacheUtil;


    /**
     * 用户登录
     * @return
     */
    @PostMapping("/login")
    public Response login(@NotEmpty(message = "账号不能为空") String account,
                          @NotEmpty(message = "密码不能为空") String password,
                          @NotEmpty(message = "验证码不能为空") String verifyCode,
                          @NotEmpty(message = "用户机器标识不能为空") String keyCode,
                          HttpServletRequest request,
                          HttpServletResponse response)throws Exception{
        // 验证码
        String redisVCode = ehcacheUtil.get(CacheConst.IMAGE_CODE + keyCode);
        if(redisVCode == null){
            return Response.error("请先获取验证码");
        }
        if(!redisVCode.equalsIgnoreCase(verifyCode)){
            return Response.error("验证码错误");
        }

        // 使用 Shiro 进行登录
        Subject subject = SecurityUtils.getSubject();
        UserAuthenticationToken token = new UserAuthenticationToken(account,password);
        subject.login(token);

        // 登录成功后，获取userid，查询该用户拥有的权限
        List<String> permissions =  userService.getUserPermissions(token.getUserId());

        // 制作JWT Token
        String jwtToken = jwtUtil.issueJWT(
                StringUtil.getRandomString(20),//令牌id
                token.getUserId() + "",//用户id
                (issuer == null ? JwtUtil.DEFAULT_ISSUER : issuer),//签发人
                null,//访问角色
                JSONArray.toJSONString(permissions),//用户权限集合，json格式
                (period == null ? JwtUtil.DEFAULT_PERIOD : period),//token有效时间
                SignatureAlgorithm.HS512
        );

        //token存入 response里的Header
        response.setHeader(WebConst.TOKEN,jwtToken);

        // 返回json
        Map<String,String> data = new HashMap<>();
        data.put("account",account);
        data.put("loginTime",new Date().getTime() + "");

        log.info("用户登录成功 ip = " + ControllerUtil.getIpAddr(request));

        // 删除验证码存储
        ehcacheUtil.delete(CacheConst.IMAGE_CODE + keyCode);

        return Response.ok();
    }
}
